import type { RoomState, DetailRecord } from '../types';
import { RoomStatus, ACMode, FanSpeed } from '../types';
import { 
  DEFAULT_TEMP, 
  INITIAL_TEMP, 
  TEMP_CHANGE_RATE, 
  TEMP_CHANGE_RATE_OFF,
  TEMP_DEVIATION_THRESHOLD,
  POWER_CONSUMPTION_RATE,
  BILLING_RATE,
  TEMP_UPDATE_INTERVAL
} from '../constants';

/**
 * 空调服务
 * 负责处理客房的温控请求，计算温度变化及费用
 */
export class ACService {
  private rooms: Map<string, RoomState> = new Map();
  private timers: Map<string, ReturnType<typeof setInterval>> = new Map();
  private callbacks: Map<string, (roomState: RoomState) => void> = new Map();

  /**
   * 初始化房间
   */
  initRoom(roomId: string, mode: ACMode): RoomState {
    const initialTemp = INITIAL_TEMP[mode];
    const roomState: RoomState = {
      roomId,
      isOn: false,
      mode,
      currentTemp: initialTemp,
      initialTemp,
      targetTemp: DEFAULT_TEMP,
      fanSpeed: FanSpeed.MEDIUM,
      status: RoomStatus.OFF,
      totalCost: 0,
      totalPowerConsumption: 0,
      lastUpdateTime: Date.now(),
      serviceStartTime: null,
      detailRecords: []
    };
    
    this.rooms.set(roomId, roomState);
    return roomState;
  }

  /**
   * 开机
   */
  turnOn(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room) return null;

    room.isOn = true;
    room.status = RoomStatus.STANDBY;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: '开机',
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 停止关机状态下的温度变化
    this.stopTempUpdate(roomId);

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 关机
   */
  turnOff(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room) return null;

    // 停止送风
    this.stopServing(roomId);

    room.isOn = false;
    room.status = RoomStatus.OFF;
    room.lastUpdateTime = Date.now();
    room.serviceStartTime = null;

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: '关机',
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 启动关机状态下的温度变化
    this.startOffTempUpdate(roomId);

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 设置目标温度
   */
  setTargetTemp(roomId: string, targetTemp: number): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) return null;

    const oldTemp = room.targetTemp;
    room.targetTemp = targetTemp;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: `调温: ${oldTemp}°C → ${targetTemp}°C`,
      targetTemp,
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 设置风速（这会触发新的服务请求）
   */
  setFanSpeed(roomId: string, fanSpeed: FanSpeed): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) return null;

    const oldSpeed = room.fanSpeed;
    room.fanSpeed = fanSpeed;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: `调风: ${oldSpeed} → ${fanSpeed}`,
      fanSpeed,
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 设置工作模式（制冷/制热）
   */
  setMode(roomId: string, mode: ACMode): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) return null;

    const oldMode = room.mode;
    room.mode = mode;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: `切换模式: ${oldMode === ACMode.COOLING ? '制冷' : '制热'} → ${mode === ACMode.COOLING ? '制冷' : '制热'}`,
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 开始送风服务
   */
  startServing(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) return null;

    room.status = RoomStatus.SERVING;
    room.serviceStartTime = Date.now();
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: `开始送风 (${room.fanSpeed})`,
      fanSpeed: room.fanSpeed,
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 启动温度更新定时器
    this.startTempUpdate(roomId);

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 停止送风服务
   */
  stopServing(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room) return null;

    const wasServing = room.status === RoomStatus.SERVING || room.status === RoomStatus.TARGET_REACHED;

    room.status = room.isOn ? RoomStatus.STANDBY : RoomStatus.OFF;
    
    if (wasServing && room.serviceStartTime) {
      const duration = Math.floor((Date.now() - room.serviceStartTime) / 1000);
      const powerConsumption = this.calculatePowerConsumption(room.fanSpeed, duration);
      const cost = powerConsumption * BILLING_RATE;

      // 费用已在updateTemperature中实时累计，这里只记录最终值
      // 不重复累加：room.totalPowerConsumption += powerConsumption;
      // 不重复累加：room.totalCost += cost;

      // 添加详单记录
      this.addDetailRecord(roomId, {
        timestamp: Date.now(),
        action: '停止送风',
        currentTemp: room.currentTemp,
        powerConsumption,
        cost,
        duration
      });
    }

    room.serviceStartTime = null;
    room.lastUpdateTime = Date.now();

    // 停止温度更新定时器
    this.stopTempUpdate(roomId);

    return room;
  }

  /**
   * 设置为等待状态
   */
  setWaiting(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room) return null;

    // 如果正在送风，先停止送风
    if (room.status === RoomStatus.SERVING) {
      this.stopServing(roomId);
    }

    room.status = RoomStatus.WAITING;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: '进入等待队列',
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 设置为待机状态
   */
  setStandby(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) return null;

    room.status = RoomStatus.STANDBY;
    room.lastUpdateTime = Date.now();

    // 添加详单记录
    this.addDetailRecord(roomId, {
      timestamp: Date.now(),
      action: '退出等待，进入待机',
      currentTemp: room.currentTemp,
      powerConsumption: 0,
      cost: 0,
      duration: 0
    });

    // 触发状态变化回调，立即更新UI
    this.triggerCallback(roomId, room);

    return room;
  }

  /**
   * 启动温度更新定时器（送风中）
   */
  private startTempUpdate(roomId: string): void {
    this.stopTempUpdate(roomId); // 先停止旧的定时器

    const timer = setInterval(() => {
      this.updateTemperature(roomId);
    }, TEMP_UPDATE_INTERVAL);

    this.timers.set(roomId, timer);
  }

  /**
   * 启动温度更新定时器（关机状态）
   */
  private startOffTempUpdate(roomId: string): void {
    this.stopTempUpdate(roomId);

    const timer = setInterval(() => {
      const room = this.rooms.get(roomId);
      if (!room || room.isOn) {
        this.stopTempUpdate(roomId);
        return;
      }

      // 关机状态下温度向初始温度变化
      const targetTemp = room.initialTemp;
      const currentTemp = room.currentTemp;
      
      if (Math.abs(currentTemp - targetTemp) < 0.1) {
        // 已经接近初始温度，停止变化
        room.currentTemp = targetTemp;
        this.stopTempUpdate(roomId);
        return;
      }

      // 计算温度变化
      const changeRate = TEMP_CHANGE_RATE_OFF / 60; // 转换为每秒变化率
      const direction = targetTemp > currentTemp ? 1 : -1;
      room.currentTemp += direction * changeRate;

      // 触发回调
      this.triggerCallback(roomId, room);
    }, TEMP_UPDATE_INTERVAL);

    this.timers.set(roomId, timer);
  }

  /**
   * 停止温度更新定时器
   */
  private stopTempUpdate(roomId: string): void {
    const timer = this.timers.get(roomId);
    if (timer) {
      clearInterval(timer);
      this.timers.delete(roomId);
    }
  }

  /**
   * 更新温度
   */
  private updateTemperature(roomId: string): void {
    const room = this.rooms.get(roomId);
    // 服务中或达到目标温度状态都需要更新温度
    if (!room || (room.status !== RoomStatus.SERVING && room.status !== RoomStatus.TARGET_REACHED)) {
      return;
    }

    const { currentTemp, targetTemp, fanSpeed, mode } = room;

    // 🔥 实时累加费用（仅SERVING状态）- 增量累计，不清零
    if (room.status === RoomStatus.SERVING && room.serviceStartTime) {
      const now = Date.now();
      const lastTime = room.lastUpdateTime || room.serviceStartTime;
      const incrementSeconds = Math.floor((now - lastTime) / 1000);
      
      if (incrementSeconds > 0) {
        // 计算这段时间的增量费用
        const incrementPower = this.calculatePowerConsumption(fanSpeed, incrementSeconds);
        const incrementCost = incrementPower * BILLING_RATE;
        
        // 增量累加（不清零，保持之前的累计值）
        room.totalPowerConsumption += incrementPower;
        room.totalCost += incrementCost;
      }
    }

    // 检查是否已达到目标温度（仅在SERVING状态检查）
    if (room.status === RoomStatus.SERVING && Math.abs(currentTemp - targetTemp) < 0.1) {
      room.currentTemp = targetTemp;
      room.status = RoomStatus.TARGET_REACHED;
      
      // 添加详单记录
      this.addDetailRecord(roomId, {
        timestamp: Date.now(),
        action: '达到目标温度，停止送风',
        currentTemp: room.currentTemp,
        powerConsumption: 0,
        cost: 0,
        duration: 0
      });

      this.triggerCallback(roomId, room);
      // 不再继续改变温度，但定时器会继续监控温度偏离
      return;
    }

    // TARGET_REACHED状态下监控温度变化（环境影响）
    if (room.status === RoomStatus.TARGET_REACHED) {
      const envChangeRate = TEMP_CHANGE_RATE_OFF / 60; // 环境影响：0.5度/分钟
      const direction = mode === ACMode.COOLING ? 1 : -1; // 环境会让温度回归
      room.currentTemp += direction * envChangeRate;
      room.lastUpdateTime = Date.now();
      this.triggerCallback(roomId, room);
      return;
    }

    // 计算温度变化（SERVING状态）
    const changeRate = TEMP_CHANGE_RATE[fanSpeed] / 60; // 转换为每秒变化率
    const direction = mode === ACMode.COOLING ? -1 : 1;
    
    // 确保不会越过目标温度
    const tempDiff = Math.abs(targetTemp - currentTemp);
    const actualChange = Math.min(changeRate, tempDiff);
    
    room.currentTemp += direction * actualChange;
    room.lastUpdateTime = Date.now();

    // 触发回调
    this.triggerCallback(roomId, room);
  }

  /**
   * 检查是否需要重新启动（温度偏离目标温度超过阈值）
   */
  checkRestart(roomId: string): boolean {
    const room = this.rooms.get(roomId);
    if (!room || !room.isOn) {
      return false;
    }

    // 只有待机状态才检查是否需要重启（送风中的不需要）
    if (room.status !== RoomStatus.STANDBY && room.status !== RoomStatus.TARGET_REACHED) {
      return false;
    }

    const tempDiff = Math.abs(room.currentTemp - room.targetTemp);
    
    // 如果温度偏离超过阈值，需要重新启动
    if (tempDiff > TEMP_DEVIATION_THRESHOLD) {
      return true;
    }

    return false;
  }

  /**
   * 计算耗电量（度）
   */
  private calculatePowerConsumption(fanSpeed: FanSpeed, durationSeconds: number): number {
    const ratePerMinute = POWER_CONSUMPTION_RATE[fanSpeed];
    const durationMinutes = durationSeconds / 60;
    return ratePerMinute * durationMinutes;
  }

  /**
   * 获取当前费用信息
   */
  getCurrentCost(roomId: string): { powerConsumption: number; cost: number; duration: number } {
    const room = this.rooms.get(roomId);
    if (!room) {
      return { powerConsumption: 0, cost: 0, duration: 0 };
    }

    // 如果房间正在送风或已达到目标温度，且有服务开始时间
    if (room.serviceStartTime && (room.status === RoomStatus.SERVING || room.status === RoomStatus.TARGET_REACHED)) {
      const duration = Math.floor((Date.now() - room.serviceStartTime) / 1000);
      const powerConsumption = this.calculatePowerConsumption(room.fanSpeed, duration);
      const cost = powerConsumption * BILLING_RATE;
      return { powerConsumption, cost, duration };
    }

    return { powerConsumption: 0, cost: 0, duration: 0 };
  }

  /**
   * 添加详单记录
   */
  private addDetailRecord(roomId: string, record: DetailRecord): void {
    const room = this.rooms.get(roomId);
    if (room) {
      room.detailRecords.push(record);
    }
  }

  /**
   * 获取房间状态（返回拷贝，确保Vue能检测到变化）
   */
  getRoomState(roomId: string): RoomState | null {
    const room = this.rooms.get(roomId);
    if (!room) return null;
    // 返回浅拷贝，这样每次都是新对象引用，Vue能检测到变化
    return { ...room };
  }

  /**
   * 获取所有房间状态（返回拷贝，确保Vue能检测到变化）
   */
  getAllRoomStates(): RoomState[] {
    return Array.from(this.rooms.values()).map(room => ({ ...room }));
  }

  /**
   * 注册状态变化回调
   */
  onStateChange(roomId: string, callback: (roomState: RoomState) => void): void {
    this.callbacks.set(roomId, callback);
  }

  /**
   * 触发回调
   */
  private triggerCallback(roomId: string, roomState: RoomState): void {
    const callback = this.callbacks.get(roomId);
    if (callback) {
      callback(roomState);
    }
  }

  /**
   * 清理房间（退房时）
   * 完全清除房间的所有状态，包括温度、费用记录、定时器等
   */
  cleanupRoom(roomId: string): void {
    // 停止温度更新定时器
    this.stopTempUpdate(roomId);
    
    // 删除状态变化回调
    this.callbacks.delete(roomId);
    
    // 删除房间状态，使房间回到未初始化状态
    this.rooms.delete(roomId);
  }

  /**
   * 清理所有定时器
   */
  destroy(): void {
    this.timers.forEach(timer => clearInterval(timer));
    this.timers.clear();
    this.callbacks.clear();
  }
}

